abstract class Equipment {
    declare private _name: string
    constructor(name: string) {
        this._name = name
    }
    getName(): string {
        return this._name
    }
    abstract power(): number
    abstract netPrice(): number
    abstract discountPrice(): number
    abstract add(e: Equipment): void
    abstract remove(e: Equipment): void
    abstract createlterator(): Iterator<Equipment>;
    abstract display(): void
}

class FloppyDisk extends Equipment {
    constructor(name: string) {
        super(name)
    }
    power(): number {
        return 3
    }
    netPrice(): number {
        return 30
    }
    discountPrice(): number {
        return 25
    }
    add(e: Equipment): void {
        throw new Error("不适应该设备")
    }
    remove(e: Equipment): void {
        throw new Error("不适应该设备")
    }
    createlterator(): Iterator<Equipment> {
        throw new Error("不适应该设备")
    }
    display(): void {
        console.log(this.getName());
    }
}

class CompositeEquipment extends Equipment {

    private _equipment: Array<Equipment> = []
    constructor(name: string) {
        super(name)
    }
    power(): number {
        const i = this.createlterator()
        let total = 0
        let r = i.next()
        while (!r.done) {
            total += r.value.power()
            r = i.next()
        }
        return total
    }
    netPrice(): number {
        const i = this.createlterator()
        let total = 0
        let r = i.next()
        while (!r.done) {
            total += r.value.netPrice()
            r = i.next()
        }
        return total
    }
    discountPrice(): number {
        const i = this.createlterator()
        let total = 0
        let r = i.next()
        while (!r.done) {
            total += r.value.discountPrice()
            r = i.next()
        }
        return total
    }
    add(e: Equipment): void {
        this._equipment.push(e)
    }
    remove(e: Equipment): void {
        let filteredArray = this._equipment.filter(item => item !== e);
        this._equipment = filteredArray
    }
    createlterator(): Iterator<Equipment> {
        return this._equipment[Symbol.iterator]();
    }
    display(): void {
        const msg: string[] = []
        console.log(this._equipment.length);
        for (let i = 0; i < this._equipment.length; i++) {
            msg.push('-')
        }
        console.log(msg.join(''));
    }
}

class Chassis extends CompositeEquipment {
    constructor(name: string) {
        super(name)
    }
}

class Cabinet extends CompositeEquipment {
    constructor(name: string) {
        super(name)
    }
}
class Bus extends CompositeEquipment {
    constructor(name: string) {
        super(name)
    }
}
class Card extends Equipment {
    constructor(name: string) {
        super(name)
    }
    power(): number {
        return 50
    }
    netPrice(): number {
        return 400
    }
    discountPrice(): number {
        return 350
    }
    add(e: Equipment): void {
        throw new Error("不适应该设备")
    }
    remove(e: Equipment): void {
        throw new Error("不适应该设备")
    }
    createlterator(): Iterator<Equipment> {
        throw new Error("不适应该设备")
    }
    display(): void {
        console.log(this.getName());
    }
}


const cabinet = new Cabinet('PC Cabinet')
const chassis = new Chassis('PC Chassis')
cabinet.add(chassis)

const bus = new Bus('MAC Bus')
bus.add(new Card('16Mbs Token Ring'))
chassis.add(bus)
chassis.add(new FloppyDisk('3.5in Floppy'))
chassis.add(new FloppyDisk('3.5in Floppy2'))

console.log(cabinet);
console.log('the net price is ' + cabinet.netPrice());

cabinet.display()